package com.ktdaddy.service.impl;

import com.ktdaddy.enums.WhaleErrorCode;
import com.ktdaddy.exception.BusinessRuntimeException;
import com.ktdaddy.request.UserQueryReq;
import com.ktdaddy.utils.PageResult;
import com.ktdaddy.vo.PermissionNodeVO;
import com.ktdaddy.vo.RoleInfoVO;
import com.ktdaddy.manager.PermissionManager;
import com.ktdaddy.manager.RoleManager;
import com.ktdaddy.manager.UserManager;
import com.ktdaddy.request.UserReq;
import com.ktdaddy.pojo.Kernel;
import com.ktdaddy.pojo.User;
import com.ktdaddy.response.UserInfoResp;
import com.ktdaddy.service.UserService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author kdaddy@163.com
 * @date 2021/4/25 23:28
 */
@Service
public class UserServiceImpl implements UserService {
    @Resource
    private UserManager userManager;

    @Resource
    private RoleManager roleManager;

    @Resource
    private PermissionManager permissionManager;



    @Override
    public Kernel getKernelByKernelName(String kernelName) {
        Kernel kernel = userManager.getByKernelName(kernelName);
        return kernel;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public Integer registerUserInfo(UserReq userBO) {
        // 生成关键用户信息
        Kernel kernel = userManager.saveKernelInfo(userBO);
        // 生成用户信息
        userManager.saveUserInfo(userBO,kernel.getId());
        return kernel.getId();
    }

    @Override
    public UserInfoResp getUserInfo() {
        UserInfoResp userInfoResp = new UserInfoResp();
        Kernel kernel = (Kernel) SecurityUtils.getSubject().getPrincipal();
        User user = userManager.getByKernelId(Objects.isNull(kernel)?0:kernel.getId());

        if(Objects.isNull(user) || Objects.isNull(kernel)){
            return userInfoResp;
        }

        userInfoResp.setRealName(user.getName());
        userInfoResp.setSlogan(user.getSlogan());
        userInfoResp.setUserId(user.getId());
        userInfoResp.setKernelName(kernel.getKernelName());
        userInfoResp.setAvatar(user.getAvatar());
        userInfoResp.setRoles(roleManager.findRoleByKernelId(kernel.getId()));
        return userInfoResp;
    }

    @Override
    public List<String> getPermCode() {
        List<String> result = new ArrayList<>();
        Kernel kernel = (Kernel) SecurityUtils.getSubject().getPrincipal();
        if(Objects.isNull(kernel)){
            return result;
        }
        List<RoleInfoVO> roleInfoBOList = roleManager.findRoleByKernelId(kernel.getId());

        List<Integer> roleIds = roleInfoBOList.stream().map(RoleInfoVO::getId).collect(Collectors.toList());

        //根据CODE获取permission
        result = permissionManager.findPermissionByRoleIds(roleIds);
        return result;
    }

    @Override
    public List<PermissionNodeVO> getMenuList() {
        List<PermissionNodeVO> nodeResult = new ArrayList<>();
        Kernel kernel = (Kernel) SecurityUtils.getSubject().getPrincipal();
        if(Objects.isNull(kernel)){
            return nodeResult;
        }

        // 获取所有一级权限树
        List<PermissionNodeVO> rootPermissionNode = permissionManager.findRootPermissionByKernelId(kernel.getId());

        if(!CollectionUtils.isEmpty(rootPermissionNode)){
            for(PermissionNodeVO permissionNodeBO : rootPermissionNode){
                fetchAndBuildChildren(permissionNodeBO);
                nodeResult.add(permissionNodeBO);
            }
        }

        return nodeResult;
    }

    @Override
    public PageResult getUserListByPage(UserQueryReq deptQueryReq) {
        return userManager.getUserListByPage(deptQueryReq);
    }

    @Override
    public Integer createUser(UserReq userReq) {
        // 生成关键用户信息
        Kernel kernel = userManager.createUser(userReq);
        return kernel.getId();
    }

    @Override
    public Integer updateUser(UserReq userReq) {
        //获取原始的User以及Kernel以及角色信息
        User oldUser = userManager.getUserById(userReq.getId());
        if(Objects.isNull(oldUser)){
            throw new BusinessRuntimeException(WhaleErrorCode.USER_NOT_EXIST);
        }
        Kernel oldKernel = userManager.getKernelById(oldUser.getKernelId());
        if(Objects.isNull(oldKernel)){
            throw new BusinessRuntimeException(WhaleErrorCode.KERNEL_NOT_EXIST);
        }
        Kernel kernelByName = userManager.getByKernelName(userReq.getKernelName());
        if(!Objects.isNull(kernelByName) && !kernelByName.getId().equals(oldKernel.getId())){
            throw new BusinessRuntimeException(WhaleErrorCode.KERNEL_NAME_EXIST);
        }
        Kernel kernelByMobile = userManager.getKernelByMobile(userReq.getMobile());
        if(!Objects.isNull(kernelByMobile) && !kernelByMobile.getId().equals(oldKernel.getId())){
            throw new BusinessRuntimeException(WhaleErrorCode.KERNEL_MOBILE_EXIST);
        }
        Kernel kernelByEmail = userManager.getKernelByEmail(userReq.getEmail());
        if(!Objects.isNull(kernelByEmail) && !kernelByEmail.getId().equals(oldKernel.getId())){
            throw new BusinessRuntimeException(WhaleErrorCode.KERNEL_EMAIL_EXIST);
        }
        //更新编辑之后的信息
        Integer kernelId = userManager.updateUser(oldKernel,oldUser,userReq);
        return kernelId;
    }

    @Override
    public List<PermissionNodeVO> getAllMenuList() {
        List<PermissionNodeVO> nodeResult = new ArrayList<>();
        // 获取所有一级权限树
        List<PermissionNodeVO> rootPermissionNode = permissionManager.findRootPermission();

        if(!CollectionUtils.isEmpty(rootPermissionNode)){
            for(PermissionNodeVO permissionNodeBO : rootPermissionNode){
                fetchAndBuildChildren(permissionNodeBO);
                nodeResult.add(permissionNodeBO);
            }
        }

        return nodeResult;
    }


    /**
     * 递归获取并且构建子节点
     * @param permissionNodeBO
     */
    private void fetchAndBuildChildren(PermissionNodeVO permissionNodeBO) {
        List<PermissionNodeVO> children = permissionManager.findPermissionByParentId(permissionNodeBO.getId());
        if(!children.isEmpty()){
            for(PermissionNodeVO child : children){
                fetchAndBuildChildren(child);
            }
            permissionNodeBO.setChildren(children);
        }
    }
}
